﻿#include <QMutex>
#include "cinterface.h"
QMutex              msgMutex;
QList<QByteArray>   msgQueue;
int GetMessage(char* msg) {
    QMutexLocker lock(&msgMutex);
    if(msgQueue.isEmpty()) return 0;

    QByteArray szByte = msgQueue.first();
    msgQueue.removeFirst();

    if(szByte.length() >= 0x400) return 0;
    memcpy(msg, szByte.data(), szByte.length());
    return szByte.length();
}

#include <QString>
#include <QStringList>
#include <QBuffer>
#include <QProcess>
#include <QDebug>
#include <QDateTime>
#include <QQuickView>
#include <QList>
#include <QGuiApplication>
#include "cproxyconnect.h"
#include "../public/CSocket.h"
#include "../public/CopyData.h"

QStringList         PjIpAddressList;
QList<CSocket*>     sockets;
QMutex              globMutex;


void PopMsgShow(const char* str) {
    if(CsGetConfig("禁用弹出提示框")[0] == '1') {
        QMutexLocker lock(&msgMutex);
        if(msgQueue.length() > 128) msgQueue.removeFirst();
        msgQueue.append(QString(str).toLocal8Bit());
    } else {
        MessageBoxA(NULL, QString(str).toLocal8Bit(), QString("评价消息").toLocal8Bit(), MB_OK);
    }
}

static QString PjIpAddress = QString(CsGetVCallConfig("可视化配置"))!=""?CsGetVCallConfig("评价器命令接收IP"):CsGetConfig("评价器命令接收IP");

int StartAdb = 3;
void StartAdbProxy(bool reconnect = false) {
    if(PjIpAddress.left(3) == "usb") {
        if(!reconnect && CProxyConnect::Instance().ProxyStarted())
            return;

        qDebug() << "StartAdbProxy Check";
        if(--StartAdb <= 0) {
            qDebug() << "StartAdbProxy Begin";
            QStringList szArg = PjIpAddress.split(':', QString::SkipEmptyParts);
            //HTTP通信转发
            QStringList forwardHttp;
            if(szArg.length() > 1) {
                forwardHttp.append("-s");
                forwardHttp.append(szArg[1]);
            }
            forwardHttp.append("forward");
            forwardHttp.append("tcp:9900");
            forwardHttp.append("tcp:9900");
            QProcess::execute("adb.exe", forwardHttp);

            //TCP通信转发
            QStringList forwardTcp;
            if(szArg.length() > 1) {
                forwardTcp.append("-s");
                forwardTcp.append(szArg[1]);
            }
            forwardTcp.append("forward");
            forwardTcp.append("tcp:9906");
            forwardTcp.append("tcp:9901");
            QProcess::execute("adb.exe", forwardTcp);
            StartAdb = 3;
        }

        CProxyConnect::Instance().Reset();
        int i = 0;

        while(i < 10) {
            if(CProxyConnect::Instance().ProxyStarted()) {
                break;
            }
            Sleep(2000);
            i++;
        }
        if(i >= 10) {
            if(CsGetConfig("USB断线时退出")[0] == '1')
                exit(0);

            PopMsgShow("请检查USB线通信是否正常");
        }
    }
}

void HearThread(void*) {
    while(true) {
        //改成10秒心跳一次
        Sleep(10000);
        IsPageVisible("PausePage");
    }
}

bool Init() {
    static bool init = false;

    if(!init) {
        qApp->addLibraryPath("./plugins");
        //以后要改成设置标识,标识的机器现在写成IP
        if(PjIpAddress.left(3) == "usb") {
            PjIpAddressList.append("127.0.0.1:9906");

            //其它IP也要通知
            QStringList szip = PjIpAddress.split(';', QString::SkipEmptyParts);
            for(int i = 1; i < szip.count(); i++) {
                PjIpAddressList.append(szip[i] + ":9901");
            }

            //启动代理连接
            CProxyConnect::Instance().start();
        } else {
            PjIpAddressList = PjIpAddress.split(';', QString::SkipEmptyParts);
            for(int i = 0; i < PjIpAddressList.length(); i++)
                PjIpAddressList[i] += ":9901";
        }

        //心跳连接
        //_beginthread(HearThread, 0, NULL);

        init = true;
    }

    if(!sockets.empty()) return true;
    StartAdbProxy();
    for(QStringList::Iterator i = PjIpAddressList.begin(); i != PjIpAddressList.end(); i++) {
        CSocket* socket = new CSocket();
        QString& PjIpAddress = *i;
        bool isUsb = (PjIpAddress == "127.0.0.1:9906");
        QStringList strList = PjIpAddress.split(':', QString::SkipEmptyParts);
        if(!socket->Connect(strList[0].toLocal8Bit(), strList[1].toInt())) {
            if(isUsb) StartAdbProxy(true);
            delete socket;
            continue;
        }
        sockets.push_back(socket);
    }

    return true;
}

void CloseSocket() {
    for(QList<CSocket*>::Iterator i = sockets.begin(); i != sockets.end(); i++) {
        CSocket* socket = *i;
        delete socket;
    }
    sockets.clear();
}

#define FOR_EACH_SOCKET \
    for(QList<CSocket*>::Iterator i = sockets.begin(); i != sockets.end(); i++)\
    {\
        CSocket* socket = *i;

#define FOR_EACH_SOCKET_END }

#define RETURN_IF_FAIL(check) do { if(!check) { CloseSocket(); return false; } } while(0)

bool ShowIntroduction() {
    QMutexLocker lock(&globMutex);
    if(!Init()) return false;

    CopyData_Generic cd = { CommandID::INTRODUCE };

    FOR_EACH_SOCKET
    int len = sizeof(cd);
    RETURN_IF_FAIL(socket->Write((char*)&len, 4));
    RETURN_IF_FAIL(socket->Write((char*)&cd, len));
    RETURN_IF_FAIL(socket->Read((char*)&len, sizeof(len)));
    RETURN_IF_FAIL(len == 1);
    FOR_EACH_SOCKET_END

    CloseSocket();

    return true;
}

bool PauseService(const char* pauseType) {
    QMutexLocker lock(&globMutex);
    if(!Init()) return false;

    CopyData_PauseType cd;
    cd.cmd = CommandID::PAUSE;
    strcpy(cd.data, pauseType);

    FOR_EACH_SOCKET
    int len = sizeof(cd);
    RETURN_IF_FAIL(socket->Write((char*)&len, 4));
    RETURN_IF_FAIL(socket->Write((char*)&cd, len));
    RETURN_IF_FAIL(socket->Read((char*)&len, sizeof(len)));
    RETURN_IF_FAIL(len == 1);
    FOR_EACH_SOCKET_END

    CloseSocket();

    //弹出提示内容
    if(CsGetConfig("暂停弹出提示")[0] != '\0') {
        HWND hWND = FindWindowA("TForm1", "虚拟呼叫器V5.0");
        if(hWND) MessageBoxA(hWND, CsGetConfig("暂停弹出提示"), "温馨提示", MB_OK | MB_SYSTEMMODAL);
    }

    return true;
}

bool ServiceInfo(ServiceInfoData* d) {
    QMutexLocker lock(&globMutex);
    if(!Init()) return false;

    CopyData_UserInfo cd;
    cd.cmd = CommandID::USER_INFO;
    memcpy(cd.data, d, sizeof(*d));

    FOR_EACH_SOCKET
    int len = sizeof(cd);
    RETURN_IF_FAIL(socket->Write((char*)&len, 4));
    RETURN_IF_FAIL(socket->Write((char*)&cd, len));
    RETURN_IF_FAIL(socket->Read((char*)&len, sizeof(len)));
    RETURN_IF_FAIL(len == 1);
    FOR_EACH_SOCKET_END

    CloseSocket();

    return true;
}

bool Appraise(AppraiseData* d) {
    QMutexLocker lock(&globMutex);
    if(!Init()) return false;

    CopyData_Appraise cd;
    cd.cmd = CommandID::APPRAISE;
    memcpy(cd.data, d, sizeof(*d));

    FOR_EACH_SOCKET
    int len = sizeof(cd);
    RETURN_IF_FAIL(socket->Write((char*)&len, 4));
    RETURN_IF_FAIL(socket->Write((char*)&cd, len));
    RETURN_IF_FAIL(socket->Read((char*)&len, sizeof(len)));
    RETURN_IF_FAIL(len == 1);
    FOR_EACH_SOCKET_END

    CloseSocket();

    return true;
}

bool ViewPerson(char idService[100]) {
    QMutexLocker lock(&globMutex);
    if(!Init()) return false;

    CopyData_ViewPersonID cd;
    cd.cmd = CommandID::SPERSONID;
    memcpy(cd.data, idService, sizeof(cd.data));

    FOR_EACH_SOCKET
    int len = sizeof(cd);
    RETURN_IF_FAIL(socket->Write((char*)&len, 4));
    RETURN_IF_FAIL(socket->Write((char*)&cd, len));
    RETURN_IF_FAIL(socket->Read((char*)&len, sizeof(len)));
    RETURN_IF_FAIL(len == 1);
    FOR_EACH_SOCKET_END

    CloseSocket();

    return true;
}

bool CloseCapturePage() {
    QMutexLocker lock(&globMutex);
    if(!Init()) return false;
    CopyData_Generic cd = { CommandID::COLSE_CAPTURE_VIEW };

    FOR_EACH_SOCKET
    int len = sizeof(cd);
    RETURN_IF_FAIL(socket->Write((char*)&len, 4));
    RETURN_IF_FAIL(socket->Write((char*)&cd, len));
    RETURN_IF_FAIL(socket->Read((char*)&len, sizeof(len)));
    RETURN_IF_FAIL(len == 1);
    FOR_EACH_SOCKET_END

    CloseSocket();

    return true;
}

static QMutex checkVisibleLock;
int IsPageVisible(const char* page) {
    QMutexLocker lock(&globMutex);
    if(!Init() || sockets.size() < 1) return -2;

    QMutexLocker locker(&checkVisibleLock);

    //检测服务连接,请求太频繁，再考虑一下
//    Record cmd;
//    cmd["cmd"]      = "TimeSync";
//    Record result = ServiceDoCommand(cmd.ToString());
//    if(!result.Exists("Succ")) {
//        return -1;
//    }

    CopyData_CheckPageVisible cd;
    cd.cmd = CommandID::CHK_PAGE_VIS;
    strcpy(cd.data, page);
    int len = sizeof(cd);
    CSocket* socket = sockets[0];
    RETURN_IF_FAIL(socket->Write((char*)&len, 4));
    RETURN_IF_FAIL(socket->Write((char*)&cd, len));
    RETURN_IF_FAIL(socket->Read((char*)&len, sizeof(len)));
    if(len == 'M') {        //有弹出框内容
        //读弹出框内容长度
        RETURN_IF_FAIL(socket->Read((char*)&len, sizeof(len)));
        char msg[0x400] = {0};    //最多支持1K的文本弹出信息
        if(len >= 0x3FF) return 0;

        RETURN_IF_FAIL(socket->Read(msg, len));
        //弹出提示内容
        PopMsgShow(QString::fromUtf8(msg).toLocal8Bit());
        //读页面可视的返回
        RETURN_IF_FAIL(socket->Read((char*)&len, sizeof(len)));
    }

    CloseSocket();

    return len;
}

bool SendCaptureData(const class QBuffer& buffer) {
    QMutexLocker lock(&globMutex);
    if(!Init() || sockets.size() < 1) return 0;

    CopyData_ScreenCapture cd;
    cd.cmd = CommandID::SCREEN_CAPTURE;
    int len = sizeof(cd);
    cd.size = buffer.size();

    CSocket* socket = sockets[0];
    RETURN_IF_FAIL(socket->Write((char*)&len, 4));
    RETURN_IF_FAIL(socket->Write((char*)&cd, len));
    RETURN_IF_FAIL(socket->Write((char*)buffer.buffer().data(), cd.size));
    RETURN_IF_FAIL(socket->Read((char*)&len, sizeof(len)));
    RETURN_IF_FAIL(len == 1);

    CloseSocket();

    return len;
}

bool ServiceStart(const char* userID) {
    Record cmd;
    cmd["cmd"] = "ServiceBegin";
    cmd["UserID"] = userID;
    Record result = ServiceDoCommand(cmd.ToString());
    if((int)result["Succ"] == 1) {
        ServiceInfoData data;
        memset(&data, 0, sizeof(data));
        strcpy(data.idUser, userID);
        return ServiceInfo(&data);
    }

    return false;
}

static QString ServiceID = "";
bool ServiceEnd(const char* userID) {
    Record cmd;
    cmd["cmd"] = "ServiceEnd";
    cmd["UserID"] = userID;
    Record result = ServiceDoCommand(cmd.ToString());
    ServiceID = "";
    if((int)result["Succ"] == 1) {
        ServiceID = (const char*)result["ServiceID"];
        AppraiseData data;
        strcpy(data.idUser, userID);
        strcpy(data.serviceGuid, ServiceID.toUtf8());

        return Appraise(&data);
    }
    return false;
}

char* CityUserLogin(const char* username, const char* passwd) {
    static QByteArray empno;
    empno = "";
    Record cmd;
    cmd["cmd"]      = "UserLogin";
    cmd["username"] = username;
    cmd["password"] = passwd;
    Record result = ServiceDoCommand(cmd.ToString());
    if(result.Exists("LogRet") && QString("登录成功") == (const char*)result["LogRet"]) {
        empno = (const char*)result["Empno"];
    }
    return empno.data();
}

//有新的等待时，评价器进行语音提醒
bool WaitSound() {
    QMutexLocker lock(&globMutex);
    if(!Init()) return false;

    CopyData_Generic cd = { CommandID::WAITSOUND };

    FOR_EACH_SOCKET
    int len = sizeof(cd);
    RETURN_IF_FAIL(socket->Write((char*)&len, 4));
    RETURN_IF_FAIL(socket->Write((char*)&cd, len));
    RETURN_IF_FAIL(socket->Read((char*)&len, sizeof(len)));
    RETURN_IF_FAIL(len == 1);
    FOR_EACH_SOCKET_END

    CloseSocket();
    return true;
}
